home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / tjgold.zip / INSTALL.001 / GOLDGRID.PAS < prev    next >
Pascal/Delphi Source File  |  1995-07-12  |  42KB  |  1,403 lines

  1. {--------------------------------------------------------------------------}
  2. {                Product: TechnoJock's Turbo Toolkit                       }
  3. {                Version: GOLD                                             }
  4. {                Build:   1.01                                             }
  5. {                                                                          }
  6. {                Copyright 1986-1995  TechnoJock Software, Inc.            }
  7. {                           All Rights Reserved                            }
  8. {                          Restricted by License                           }
  9. {--------------------------------------------------------------------------}
  10.  
  11.                     {**********************************}
  12.                     {**       Unit:   GOLDGRID       **}
  13.                     {**********************************}
  14.  
  15. {++++++++++++++++++++++++++++++} unit GOLDGRID; {++++++++++++++++++++++++++++}
  16.  
  17. {$I GOLDFLAG.INC}
  18. {$IFNDEF GOLDGRID}
  19.    {$DEFINE GOLDGRID}
  20. {$ENDIF}
  21.  
  22. {++++++++++++++++++++++++++++++++} INTERFACE {+++++++++++++++++++++++++++++++}
  23.  
  24. uses DOS, CRT, GoldHard, GoldMisc, GoldKey, GoldFast, GoldWin, GoldLink,
  25.      GoldList, GoldIO, GoldStr, GoldTint;
  26.  
  27. type
  28.    GridSet = record
  29.       LastECode: integer;
  30.       GridCorner: char;
  31.       EMsgFunc: ErrMsgFunc;
  32.    end;
  33.  
  34. {Grid Lists}
  35. function  LastGridError: integer;
  36. procedure GridSetError(ECode:integer);
  37. procedure GridSetLocks(var ListDetails: ListCfg;LCol,LRow:byte);
  38. procedure GridAssignTabs(var ListDetails: ListCfg; TA:pGridTabArray; Dim:integer);
  39. procedure GridProcessKey(var ListDetails: ListCfg;var K:word;X,Y:byte;MakeLocal:boolean);
  40. procedure GridRefresh(var ListDetails: ListCfg; Status:gStatus);
  41. procedure RunGrid(var ListDetails: ListCfg;Tit:StrScreen);
  42. function  LaunchGrid(var ListDetails: ListCfg;Tit:StrScreen; CloseProc:ListCloseProc): byte;
  43.  
  44. var
  45.    GridVars: GridSet;
  46.  
  47. {+++++++++++++++++++++++++++++} IMPLEMENTATION {+++++++++++++++++++++++++++++}
  48.  
  49.                  {**************************************}
  50.                  {**       G R I D    L I S T S       **}
  51.                  {**************************************}
  52.  
  53. {$IFOPT F-}
  54.    {$DEFINE FOFF}
  55.    {$F+}
  56. {$ENDIF}
  57.  
  58. function GridEMsg(ECode:integer): string;
  59. {}
  60. begin
  61.    case Ecode of
  62.       0: GridEMsg := 'OK';
  63.       else
  64.          GridEMsg := 'Internal Grid error';
  65.    end; {case}
  66. end; { GridEMsg }
  67.  
  68. {$IFDEF FOFF}
  69.    {$F-}
  70.    {$UNDEF FOFF}
  71. {$ENDIF}
  72.  
  73. procedure GridSetError(ECode:integer);
  74. {}
  75. {$IFOPT D+}
  76. var Msg: string;
  77. {$ENDIF}
  78. begin
  79.    GridVars.LastEcode := ECode;
  80. {$IFOPT D+}  {if debug active display an error message and terminate}
  81.    if Ecode <> 0 then
  82.    begin
  83.       str(Ecode,Msg);
  84.       Msg := Msg+': '+GridVars.EMsgFunc(Ecode);
  85.       SetWinIgnore(true);
  86.       if PromptCustom(' GoldGrid Error ',Msg,' ~I~gnore ',' ~A~bort ','',279,286,0,0, 10000) = 2 then
  87.          Halt;
  88.    end;
  89. {$ENDIF}
  90. end; {GridSetError}
  91.  
  92. function LastGridError: integer;
  93. {}
  94. begin
  95.    LastGridError := GridVars.LastECode;
  96. end; { LastGridError }
  97.  
  98. procedure GridAssignTabs(var ListDetails: ListCfg; TA:pGridTabArray; Dim:integer);
  99. {}
  100. begin
  101.    with ListDetails do
  102.    begin
  103.       TabsArrayPtr := TA;
  104.       TabsArrayDim := Dim;
  105.    end;
  106. end; { GridAssignTabs }
  107.  
  108. procedure GridSetLocks(var ListDetails: ListCfg;LCol,LRow:byte);
  109. {}
  110. begin
  111.    with ListDetails do
  112.    begin
  113.       ColumnLock := LCol;
  114.       RowLock := LRow;
  115.    end;
  116. end; { GridSetLocks }
  117.  
  118. procedure GridAssignHeadingHook(var ListDetails: ListCfg; Proc:ListHindHook);
  119. {}
  120. begin
  121.    Listdetails.WriteHeadingsHook := Proc;
  122. end; {GridAssignHeadingHook}
  123.  
  124.                           {********************}
  125.                           {**  Grid Display  **}
  126.                           {********************}
  127.  
  128. procedure GridWriteVScrollBar(var ListDetails: ListCfg; Status:gStatus);
  129. {}
  130. var A:byte;
  131. begin
  132.    with ListDetails do
  133.    begin
  134.       if TotalNodes > succ(Y2-Y1) then {need a scroll bar}
  135.       begin
  136.          if Status in [Activate,HiStatus] then
  137.             A := Col[ListScrollbarHi]
  138.          else
  139.             A := Col[ListScrollbarNorm];
  140.          WriteVScrollBar(X2,Y1,Y2- ord(LastCol > X2-X1),A,ActiveNode,TotalNodes);
  141.       end
  142.    end;
  143. end; { GridWriteVScrollBar }
  144.  
  145. procedure GridWriteHScrollBar(var ListDetails: ListCfg; Status:gStatus);
  146. {}
  147. var A:byte;
  148. begin
  149.    with ListDetails do
  150.    begin
  151.       if LastCol > X2-X1 then {need a scroll bar}
  152.       begin
  153.          if Status in [Activate,HiStatus] then
  154.             A := Col[ListScrollbarHi]
  155.          else
  156.             A := Col[ListScrollbarNorm];
  157.          WriteHScrollBar(X1,pred(X2),Y2,A,StartingCol,LastCol);
  158.       end
  159.    end;
  160. end; {GridWriteHScrollBar}
  161.  
  162. procedure GridWriteItem(var ListDetails: ListCfg; ItemNum:longint; Status:gStatus);
  163. {}
  164. var
  165.   Y,A:byte;
  166.   Str:StrScreen;
  167.   AvailWidth,
  168.   TextWidth: shortint;
  169. begin
  170.    with ListDetails do
  171.    begin
  172.       if TotalNodes = 0 then
  173.          exit;
  174.       AvailWidth := X2 - pred(X1) - ord(TotalNodes > succ(Y2-Y1));
  175.       if ItemNum <= TotalNodes then
  176.       begin
  177.          with ListVars do
  178.             TextWidth := AvailWidth
  179.                          - length(GridLeft)
  180.                          - length(GridRight)
  181.                          - ord(AllowTagging) * length(GridTag);
  182.          if TextWidth > 0 then
  183.          begin
  184.             if (TabsArrayPtr = nil) then
  185.             begin
  186.                if (ColumnLock = 0) then
  187.                   Str := GetStr(Listdetails.DataSource,ItemNum,StartingCol,pred(StartingCol)+TextWidth)
  188.                else
  189.                begin
  190.                   Str := GetStr(Listdetails.DataSource,ItemNum,1,ColumnLock);
  191.                   Str := Str + GetStr(Listdetails.DataSource,ItemNum,StartingCol,pred(StartingCol) + TextWidth - ColumnLock);
  192.                end;
  193.             end
  194.             else
  195.             begin
  196.                if (ColumnLock <> 0) and (TabsArrayPtr^[ColumnLock] < TextWidth) then
  197.                begin
  198.                   Str := GetStr(Listdetails.DataSource,ItemNum,1,pred(TabsArrayPtr^[succ(ColumnLock)]));
  199.                   Str := Str + GetStr(Listdetails.DataSource,ItemNum,StartingCol,
  200.                                       pred(StartingCol)+TextWidth-pred(TabsArrayPtr^[succ(ColumnLock)]))
  201.                end
  202.                else
  203.                   Str := GetStr(Listdetails.DataSource,ItemNum,StartingCol,pred(StartingCol) + TextWidth - ColumnLock);
  204.             end;
  205.          end
  206.          else
  207.             Str := '';
  208.          if AllowTagging then  {add the tag character}
  209.          begin
  210.             if GetBit(DataSource,ItemNum,0) then
  211.                Str := ListVars.GridTag + Str
  212.             else
  213.                Str := replicate(length(ListVars.GridTag),' ')+Str;
  214.          end;
  215.          if AllowTwoColors and GetBit(DataSource,ItemNum,1) then
  216.             A := Col[ListNorm2]
  217.          else
  218.             A := Col[ListNorm1];
  219.          if ItemNum = ActiveNode then
  220.          begin
  221.             Str := ListVars.GridLeft + Str + ListVars.GridRight;
  222.             if (Status in [HiStatus,Activate]) then
  223.             begin
  224.                if AllowTwoColors and GetBit(DataSource,ItemNum,1) then
  225.                   A := Col[ListHi2]
  226.                else
  227.                   A := Col[ListHi1];
  228.             end;
  229.          end
  230.          else
  231.             Str := replicate(length(ListVars.GridLeft),' ')+Str+replicate(length(ListVars.GridRight),' ');
  232.       end
  233.       else
  234.       begin
  235.          A := Col[ListNorm1];
  236.          Str := replicate(AvailWidth,' ');
  237.       end;
  238.       {now we've created the item string we have to figure out where
  239.        to write it}
  240.       if RowLock = 0 then
  241.          Y := Y1+ItemNum-TopNode
  242.       else if ItemNum < RowLock then
  243.          Y := pred(Y1) + ItemNum
  244.       else
  245.          Y := Y1 + pred(RowLock) + ItemNum - TopNode;
  246.       Listdetails.ColorHook(ItemNum,ItemNum = ActiveNode,A);
  247.       WriteAT(X1,Y,A,Str);
  248.       if (Status in [HiStatus,Activate]) and (ItemNum = ActiveNode) then
  249.       begin
  250.          GridWriteVScrollBar(Listdetails,HiStatus);
  251.          gotoxy(X1,Y);
  252.       end;
  253.    end;
  254. end; { GridWriteItem }
  255.  
  256. procedure GridRefreshHeadFoot(var ListDetails: ListCfg);
  257. {}
  258. var
  259.    Counter,
  260.    I: integer;
  261.    TempStr: string;
  262.    W,X: byte;
  263.  
  264.    function GTabSubStr(var Source:string; TabPos:integer):string;
  265.    {}
  266.    begin
  267.       with Listdetails do
  268.          if TabPos <= TabsArrayDim then
  269.             GTabSubStr := TabSubStr(Source,TabPos)
  270.          else
  271.             GTabSubStr := '';
  272.    end; {GTabSubStr}
  273.  
  274.    procedure GetTitleStr(Str:string; Scroll:boolean);
  275.    {}
  276.    var
  277.       Tabs,Counter,Wid: integer;
  278.    begin
  279.       with Listdetails do
  280.       begin
  281.          if not scroll or (TabsArrayDim = 0) then
  282.          begin
  283.              if not Scroll then
  284.                 TempStr := padleft(Str,W,' ')
  285.              else
  286.              begin
  287.                 if ColumnLock <> 0 then
  288.                    TempStr := copy(Str,1,ColumnLock)
  289.                 else
  290.                    TempStr := '';
  291.                 TempStr :=  padleft(TempStr+ copy(Str,StartingCol,W),W,' ');
  292.              end;
  293.              exit;
  294.          end;
  295.          Counter := 0;
  296.          TempStr := '';
  297.          while (Counter < ColumnLock)
  298.          and (Counter < TabsArrayDim) do
  299.          begin
  300.             inc(Counter);
  301.             TempStr := TempStr + padleft(GTabSubStr(Str,Counter),
  302.                                          TabsArrayPtr^[succ(Counter)]-TabsArrayPtr^[Counter],
  303.                                          ' ');
  304.          end;
  305.          {the Locked part has now been determined}
  306.          Counter := length(TempStr);
  307.          Tabs := pred(ListDetails.TabsArrayPos);
  308.          while (Counter < W) and (Tabs < Listdetails.TabsArrayDim) do
  309.          begin
  310.             inc(Tabs);
  311.             if Tabs =  Listdetails.TabsArrayDim then
  312.                Wid := 80
  313.             else
  314.                Wid := TabsArrayPtr^[succ(Tabs)]-TabsArrayPtr^[Tabs];
  315.             TempStr := TempStr + padleft(GTabSubStr(Str,Tabs),Wid,' ');
  316.             Counter := length(TempStr);
  317.          end;
  318.          TempStr := copy(TempStr,1,W);
  319.       end;
  320.    end; {GetTitleStr}
  321.  
  322. begin
  323.    with Listdetails do
  324.    begin
  325.       Counter := 0;
  326.       if Scrollheader then
  327.          X := StartingCol
  328.       else
  329.          X := 1;
  330.       W := (X2-pred(X1))-ord(TotalNodes > succ(Y2-Y1));
  331.       for I := 1 to ListMaxHeaders do
  332.       begin
  333.          if Listdetails.Headers[I] <> nil then
  334.          begin
  335.             inc(Counter);
  336.             ClearText(succ(leftGap),TopGap+Counter,leftGap+W,TopGap+Counter,Col[ListHeaders]);
  337.             GetTitleStr(Listdetails.Headers[I]^,Scrollheader);
  338.             if (TempStr <> '') and (TempStr[1] = '^') then
  339.             begin
  340.                delete(TempStr,1,1);
  341.                WriteBetween(succ(leftGap),X2-X1-RightGap,TopGap+Counter,Col[ListHeaders],TempStr);
  342.             end
  343.             else
  344.                WriteAT(succ(leftGap),TopGap+Counter,Col[ListHeaders],TempStr);
  345.          end;
  346.       end;
  347.       Counter := 0;
  348.       if ScrollFooter then
  349.          X := StartingCol
  350.       else
  351.          X := 1;
  352.       for I := 1 to ListMaxFooters do
  353.       begin
  354.          if Listdetails.Footers[I] <> nil then
  355.          begin
  356.             inc(Counter);
  357.             ClearText(succ(leftGap),Y2+Counter,leftGap+W,TopGap+Counter,Col[ListHeaders]);
  358.             GetTitleStr(Listdetails.Footers[I]^,ScrollFooter);
  359.             if (TempStr <> '') and (TempStr[1] = '^') then
  360.             begin
  361.                delete(TempStr,1,1);
  362.                WriteBetween(succ(leftGap),X2-X1-RightGap,Y2+Counter,Col[ListHeaders],TempStr);
  363.             end
  364.             else
  365.                WriteAT(succ(leftGap),Y2+Counter,Col[ListHeaders],TempStr);
  366.          end;
  367.       end;
  368.    end;
  369. end; {GridRefreshHeadFoot}
  370.  
  371. procedure GridRefresh(var ListDetails: ListCfg; Status:gStatus);
  372. {Updates the Grid display}
  373. var
  374.   I : longint;
  375.   Hdr: string;
  376.   A,Y3: byte;
  377. begin
  378.    with ListDetails do
  379.    begin
  380.       if TabsArrayPtr <> nil then
  381.          LastCol := TabsArrayPtr^[TabsArrayDim];
  382.       if (ColumnLock > 0)
  383.       and (TabsArrayPtr <> nil)
  384.       and (StartingCol < TabsArrayPtr^[succ(ColumnLock)]) then
  385.       begin
  386.          StartingCol := TabsArrayPtr^[succ(ColumnLock)];
  387.          TabsArrayPos := succ(ColumnLock);
  388.       end;
  389.       Y3 := Y2 - ord(LastCol > X2-X1);
  390.       if (ActiveNode < TopNode)
  391.       or (ActiveNode > TopNode + Y3 - Y1) then
  392.       begin
  393.          If Y3 > Y1 then
  394.             TopNode := ActiveNode - (Y3 - Y1) div 2
  395.          else
  396.             TopNode := ActiveNode;
  397.       end;
  398.       if RowLock = 0 then
  399.          for I := TopNode to TopNode + Y3 - Y1 do
  400.             GridWriteItem(ListDetails,I,Status)
  401.       else
  402.       begin
  403.          if RowLock < (Y3 - Y1) then
  404.          begin
  405.             for I := 1 to RowLock do
  406.                GridWriteItem(ListDetails,I,Status);
  407.             for I := TopNode to TopNode + (Y3 - Y1) - RowLock do
  408.                GridWriteItem(ListDetails,I,Status);
  409.          end
  410.          else
  411.             for I := 1 to Y3 - Y1 do
  412.                GridWriteItem(ListDetails,I,Status);
  413.       end;
  414.       {time to write the headings}
  415.       GridRefreshHeadFoot(Listdetails);
  416.       WriteHeadingsHook(@Listdetails);
  417.       GridWriteHScrollBar(Listdetails,Status);
  418.       if (LastCol > X2-X1) and (TotalNodes > succ(Y2-Y1)) then
  419.       begin
  420.          if Status in [Activate,HiStatus] then
  421.             A := Col[ListScrollbarHi]
  422.          else
  423.             A := Col[ListScrollbarNorm];
  424.          WriteAT(X2,Y2,A,GridVars.GridCorner);
  425.       end;
  426.    end;
  427. end; { GridRefresh }
  428.  
  429. procedure GridWindowStretch(var Listdetails: ListCfg);
  430. {Called when user stretches the window}
  431. var
  432.    WP: WStructurePtr;
  433. begin
  434.    {First set the listdetails to reflect the revised window dimensions}
  435.    WP := WinPtr(0); {top window}
  436.    with Listdetails do
  437.    begin
  438.       WX1 := WP^.X;
  439.       WY1 := WP^.Y;
  440.       WX2 := WX1 + pred(WP^.Width);
  441.       WY2 := WY1 + pred(WP^.Depth);
  442.    end;
  443.    SetInnerDimensions(Listdetails);
  444.    GridRefresh(ListDetails,HiStatus);
  445.    WinDrawAll;
  446. end; {GridWindowStretch}
  447.  
  448.                        {****************************}
  449.                        {**  Grid Cursor Movement  **}
  450.                        {****************************}
  451.  
  452. function GridScrollUp(var ListDetails: ListCfg): boolean;
  453. {Updates the ActiveNode and TopNode parameters and returns
  454.  true if TopNode is modified, i.e. if the Grid needs to be
  455.  refreshed}
  456. var TopRow: longint;
  457. begin
  458.    GridScrollUp := false;
  459.    with ListDetails do
  460.    begin
  461.       if ActiveNode > TopNode then
  462.          dec(ActiveNode)
  463.       else
  464.       begin
  465.          if RowLock > 0 then
  466.             TopRow := succ(RowLock)
  467.          else
  468.             TopRow := 1;
  469.          if TopNode > TopRow then
  470.          begin
  471.             dec(TopNode);
  472.             ActiveNode := TopNode;
  473.             GridScrollUp := true;
  474.          end;
  475.       end;
  476.    end;
  477. end; {GridScrollUp}
  478.  
  479. function GridScrollDown(var ListDetails: ListCfg): boolean;
  480. {Updates the ActiveNode and TopNode parameters and returns
  481.  true if TopNode is modified, i.e. if the Grid needs to be
  482.  refreshed}
  483. begin
  484.    GridScrollDown := false;
  485.    with ListDetails do
  486.    begin
  487.       if ActiveNode < TotalNodes then
  488.       begin
  489.          if ActiveNode < TopNode + Y2 - Y1 - RowLock - ord(LastCol > X2-X1) then
  490.             inc(ActiveNode)
  491.          else
  492.          begin
  493.             inc(TopNode);
  494.             inc(ActiveNode);
  495.             GridScrollDown := true;
  496.          end;
  497.       end;
  498.    end;
  499. end; {GridScrollDown}
  500.  
  501. function GridScrollPgDn(var ListDetails: ListCfg): boolean;
  502. {Updates the ActiveNode and TopNode parameters and returns
  503.  true if TopNode is modified, i.e. if the Grid needs to be
  504.  refreshed}
  505. var Blockdepth: byte;
  506. begin
  507.    with ListDetails do
  508.    begin
  509.       if ActiveNode < TotalNodes then
  510.       begin
  511.          GridScrollPgDn := true;
  512.          BlockDepth := succ(Y2 - Y1) - RowLock - ord(LastCol > X2-X1);
  513.          if TopNode + Blockdepth > TotalNodes then
  514.             ActiveNode := TotalNodes
  515.          else
  516.          begin
  517.             inc(TopNode,Blockdepth);
  518.             inc(ActiveNode,Blockdepth);
  519.             if ActiveNode > TotalNodes then
  520.                ActiveNode := TotalNodes;
  521.          end;
  522.       end
  523.       else
  524.          GridScrollPgDn := false;
  525.    end;
  526. end; {GridScrollPgDn}
  527.  
  528. function GridScrollPgUp(var ListDetails: ListCfg): boolean;
  529. {Updates the ActiveNode and TopNode parameters and returns
  530.  true if TopNode is modified, i.e. if the Grid needs to be
  531.  refreshed}
  532. var Blockdepth: byte;
  533. begin
  534.    GridScrollPgUp := false;
  535.    with ListDetails do
  536.    begin
  537.       if ActiveNode > succ(RowLock) then
  538.       begin
  539.          if TopNode > succ(RowLock) then
  540.             GridScrollPgUp := true;
  541.          BlockDepth := succ(Y2 - Y1) - RowLock - ord(LastCol > X2-X1);
  542.          if TopNode - BlockDepth < succ(RowLock) then
  543.             TopNode := succ(RowLock)
  544.          else
  545.             dec(TopNode,BlockDepth);
  546.          dec(ActiveNode,Blockdepth);
  547.          if ActiveNode < TopNode then
  548.             ActiveNode := TopNode;
  549.       end;
  550.    end;
  551. end; {GridScrollPgUp}
  552.  
  553. function GridScrollHome(var ListDetails: ListCfg): boolean;
  554. {Updates the ActiveNode and TopNode parameters and returns
  555.  true if TopNode is modified, i.e. if the Grid needs to be
  556.  refreshed}
  557. begin
  558.    with ListDetails do
  559.    begin
  560.       GridScrollHome := (TopNode > succ(RowLock));
  561.       TopNode := succ(RowLock);
  562.       ActiveNode := TopNode;
  563.    end;
  564. end; {GridScrollHome}
  565.  
  566. function GridScrollEnd(var ListDetails: ListCfg): boolean;
  567. {Updates the ActiveNode and TopNode parameters and returns
  568.  true if TopNode is modified, i.e. if the Grid needs to be
  569.  refreshed}
  570. begin
  571.    with ListDetails do
  572.    begin
  573.       if TopNode + Y2 - Y1 - RowLock - ord(LastCol > X2-X1) < TotalNodes then
  574.       begin
  575.          GridScrollEnd := true;
  576.          TopNode := TotalNodes - (Y2 - Y1) + RowLock + ord(LastCol > X2-X1);
  577.       end
  578.       else
  579.          GridScrollEnd := false;
  580.       ActiveNode := TotalNodes;
  581.    end;
  582. end; {GridScrollEnd}
  583.  
  584. function GridScrollLeft(var ListDetails: ListCfg): boolean;
  585. {Updates the ActiveNode and TopNode parameters and returns
  586.  true if TopNode is modified, i.e. if the list needs to be
  587.  refreshed}
  588. var
  589.   PrevPos: integer;
  590.   TempStr: string;
  591. begin
  592.    with ListDetails do
  593.    begin
  594.       if (StartingCol = 1)
  595.       or ((ColumnLock > 0) and (ColumnLock = pred(StartingCol))) then
  596.          GridScrollLeft := false
  597.       else
  598.       begin
  599.          GridScrollLeft := true;
  600.          if TabsArrayPtr <> nil then {use Tab Array to determine next tabstop}
  601.          begin
  602.             if TabsArrayPos > 1 then
  603.             begin
  604.                dec(TabsArrayPos);
  605.                StartingCol := TabsArrayPtr^[TabsArrayPos];
  606.                if StartingCol < ColumnLock then
  607.                   StartingCol := succ(ColumnLock);
  608.             end;
  609.          end
  610.          else
  611.             StartingCol := pred(StartingCol);
  612.       end;
  613.    end;
  614. end; {GridScrollLeft}
  615.  
  616. function GridScrollRight(var ListDetails: ListCfg): boolean;
  617. {Updates the ActiveNode and TopNode parameters and returns
  618.  true if TopNode is modified, i.e. if the list needs to be
  619.  refreshed}
  620. var
  621.   NextPos: integer;
  622.   TempStr: string;
  623. begin
  624.    with ListDetails do
  625.    begin
  626.       if StartingCol = LastCol then
  627.          GridScrollRight := false
  628.       else
  629.       begin
  630.          GridScrollRight := true;
  631.          if TabsArrayPtr <> nil then {use TabString to determine next tabstop}
  632.          begin
  633.             if TabsArrayPos < TabsArrayDim then
  634.             begin
  635.                inc(TabsArrayPos);
  636.                StartingCol := TabsArrayPtr^[TabsArrayPos];
  637.                if StartingCol < ColumnLock then
  638.                   StartingCol := succ(ColumnLock);
  639.             end;
  640.          end
  641.          else
  642.          begin
  643.            StartingCol := succ(StartingCol);
  644.                if StartingCol < ColumnLock then
  645.                   StartingCol := succ(ColumnLock);
  646.  
  647.          end;
  648.       end;
  649.    end;
  650. end; {GridScrollRight}
  651.  
  652. function GridScrollChar(var ListDetails: ListCfg;Ch:char): boolean;
  653. {Updates the ActiveNode and TopNode parameters and returns
  654.  true if TopNode is modified, i.e. if the list needs to be
  655.  refreshed}
  656. var
  657.    LastPick,
  658.    L: longint;
  659.    Str:string[1];
  660.    Found:boolean;
  661. begin
  662.    GridScrollChar := false;
  663.    with ListDetails do
  664.    begin
  665.       {first search from top of list looking for match}
  666.       L := 0;
  667.       Found := false;
  668.       while not found and (L <= TotalNodes) do
  669.       begin
  670.          inc(L);
  671.          Str := GetStr(Listdetails.DataSource,L,1,1);
  672.          Found := Str[1] = Ch;
  673.       end;
  674.       if Found then
  675.       begin
  676.          ActiveNode := L;
  677.          if (ColCount = 1) or (LastColWidth = RealColWidth) then
  678.             LastPick := ColCount * RowCount
  679.          else
  680.             LastPick := pred(ColCount) * RowCount;
  681.          if (ActiveNode < TopNode)
  682.          or (ActiveNode > pred(TopNode) + LastPick) then
  683.          begin
  684.             TopNode := ActiveNode;
  685.             GridScrollChar := true;
  686.          end;
  687.       end;
  688.    end;
  689. end; {GridScrollChar}
  690.  
  691. procedure GridMoveIt(var ListDetails: ListCfg; Direction: byte);
  692. {}
  693. var
  694.   Repaint: boolean;
  695.   OldAct: integer;
  696. begin
  697.    with ListDetails do
  698.    begin
  699.       OldAct := ActiveNode;
  700.       if ((Direction in [1,3,5]) and (ActiveNode = 1))
  701.       or ((Direction in [2,4,6]) and (ActiveNode = TotalNodes)) then
  702.          exit;
  703.       case Direction of
  704.         1: Repaint := GridScrollUp(ListDetails);
  705.         2: Repaint := GridScrollDown(ListDetails);
  706.         3: Repaint := GridScrollPgUp(ListDetails);
  707.         4: Repaint := GridScrollPgDn(ListDetails);
  708.         5: Repaint := GridScrollHome(ListDetails);
  709.         6: Repaint := GridScrollEnd(ListDetails);
  710.         7: Repaint := GridScrollLeft(ListDetails);
  711.         8: Repaint := GridScrollRight(ListDetails);
  712.       end;
  713.       if Repaint then
  714.          GridRefresh(ListDetails,HiStatus)
  715.       else if OldAct <> ActiveNode then
  716.       begin
  717.          GridWriteItem(ListDetails,OldAct,HiStatus);
  718.          GridWriteItem(ListDetails,ActiveNode,HiStatus);
  719.       end;
  720.    end;
  721. end; { GridMoveIt }
  722.  
  723.                           {*********************}
  724.                           {**  Tagging Procs  **}
  725.                           {*********************}
  726.  
  727. procedure ToggleTagState(var ListDetails: ListCfg);
  728. {}
  729. begin
  730.    with ListDetails do
  731.    if AllowTagging then
  732.    begin
  733.       SetBit(DataSource,ActiveNode,TagBit,not GetBit(DataSource,ActiveNode,TagBit));
  734.       GridWriteItem(Listdetails,ActiveNode,HiStatus);
  735.    end;
  736. end; { ToggleTagState }
  737.  
  738. procedure SetTag(var ListDetails: ListCfg; On: boolean);
  739. {}
  740. var State: boolean;
  741. begin
  742.    with ListDetails do
  743.    if AllowTagging then
  744.    begin
  745.       State := GetBit(DataSource,ActiveNode,TagBit);
  746.       if State <> On then
  747.       begin
  748.          SetBit(DataSource,ActiveNode,TagBit,On);
  749.          GridWriteItem(Listdetails,ActiveNode,HiStatus);
  750.       end;
  751.    end;
  752. end; { SetTag }
  753.  
  754. procedure SetTagAll(var ListDetails: ListCfg; On: boolean);
  755. {}
  756. var I : longint;
  757. begin
  758.    with ListDetails do
  759.    if AllowTagging then
  760.    begin
  761.       for I := 1 to TotalNodes do
  762.          SetBit(DataSource,I,TagBit,On);
  763.       GridRefresh(ListDetails,HiStatus)
  764.    end;
  765. end; { SetTagAll }
  766.  
  767.                        {***************************}
  768.                        {**  Grid Mouse Handling  **}
  769.                        {***************************}
  770.  
  771. procedure GridMouseVScroll(var ListDetails: ListCfg);
  772. {}
  773. var
  774.   L,M,R: boolean;
  775.   TopY,BotY,
  776.   X,Y,ElevatorY:byte;
  777.   WaitTime: integer;
  778.  
  779.   procedure ScrollUpOne;
  780.   {}
  781.   begin
  782.      with ListDetails do
  783.      repeat
  784.         MouseStatusWin(L,M,R,X,Y);
  785.         if (X = X2) and (Y = TopY) and L then
  786.            GridMoveIt(Listdetails,1);
  787.         DelayIt(L,InWindow,WaitTime);
  788.      until not L;
  789.   end; { ScrollUpOne }
  790.  
  791.   procedure ScrollDownOne;
  792.   {}
  793.   begin
  794.      with ListDetails do
  795.      repeat
  796.         MouseStatusWin(L,M,R,X,Y);
  797.         if (X = X2) and (Y = BotY) and L then
  798.            GridMoveIt(ListDetails,2);
  799.         DelayIt(L,InWindow,WaitTime);
  800.      until not L;
  801.   end; { ScrollDownOne }
  802.  
  803.   procedure ScrollUpward;
  804.   {}
  805.   begin
  806.      with ListDetails do
  807.      repeat
  808.         MouseStatusWin(L,M,R,X,Y);
  809.         if ActiveNode <> 1 then
  810.         begin
  811.            if (X = X2) and (Y >= TopY) and (Y <= ElevatorY) and L then
  812.               GridMoveIt(ListDetails,3);   {PgUp effect}
  813.            DelayIt(L,InWindow,WaitTime);
  814.         end;
  815.      until not L;
  816.   end; { ScrollUpward }
  817.  
  818.   procedure ScrollDownward;
  819.   {}
  820.   begin
  821.      with ListDetails do
  822.      repeat
  823.         MouseStatusWin(L,M,R,X,Y);
  824.         if ActiveNode <> TotalNodes then
  825.         begin
  826.            if (X = X2) and (Y <= Y2) and (Y >= ElevatorY) and L then
  827.               GridMoveIt(ListDetails,4);   {PgDn effect}
  828.            DelayIt(L,InWindow,WaitTime);
  829.         end;
  830.      until not L;
  831.   end; { ScrollDownward }
  832.  
  833.   procedure ScrollDragElevator;
  834.   {}
  835.   var
  836.     OldY:byte;
  837.     NewActive:longint;
  838.   begin
  839.      OldY := Y;
  840.      with ListDetails do
  841.      repeat
  842.         MouseStatusWin(L,M,R,X,Y);
  843.         if (X = X2) and (Y < BotY) and (Y > TopY) and (Y <> OldY) and L then
  844.         begin
  845.            OldY := Y;
  846.            if Y = succ(TopY) then
  847.               NewActive := 1
  848.            else if Y = pred(BotY) then
  849.               NewActive := TotalNodes
  850.            else
  851.               NewActive := TotalNodes * (Y - TopY) div (BotY-TopY);
  852.            if NewActive <> ActiveNode then
  853.            begin
  854.               ActiveNode := NewActive;
  855.               TopNode := NewActive;
  856.               GridRefresh(ListDetails,HiStatus);
  857.            end;
  858.            if WindowHasFocus then
  859.               WinDrawTop;
  860.         end;
  861.      until not L;
  862.   end; { ScrollElevator }
  863.  
  864. begin
  865.    with ListDetails do
  866.    begin
  867.       InWindow := WindowHasFocus;
  868.       WaitTime := KeyVars.InitScrollDelay;
  869.       repeat
  870.          MouseStatusWin(L,M,R,X,Y);
  871.          if L and (X = X2) then
  872.          begin
  873.             TopY := Y1;
  874.             BotY := Y2 - ord(LastCol > X2-X1);
  875.             if Y = TopY then
  876.                ScrollUpOne
  877.             else if Y = BotY then
  878.                ScrollDownOne
  879.             else    {mouse pressed along scroll bar body}
  880.             begin
  881.                ElevatorY := GetVScrollBarElevator(TopY,BotY,ActiveNode,TotalNodes);
  882.                if ((Y = succ(TopY)) and (Y=ElevatorY) and (ActiveNode > RowLock))
  883.                or (Y > TopY) and (Y < ElevatorY) then
  884.                   ScrollUpward
  885.                else if ((Y = pred(BotY)) and (Y=ElevatorY)
  886.                         and
  887.                         (ActiveNode < TotalNodes)
  888.                        )
  889.                        or ((Y < BotY) and (Y > ElevatorY))  then
  890.                   ScrollDownward
  891.                else {user is dragging elevator}
  892.                   ScrollDragElevator;
  893.              end;
  894.          end;
  895.       until not L;
  896.       MouseRelease;
  897.    end;
  898. end; { GridMouseVScroll }
  899.  
  900. procedure GridMouseHScroll(var ListDetails: ListCfg);
  901. {}
  902. var
  903.   L,M,R: boolean;
  904.   TopY,BotY,
  905.   X,Y,ElevatorX:byte;
  906.   WaitTime: integer;
  907.  
  908.   procedure ScrollLeftOne;
  909.   {}
  910.   begin
  911.      with ListDetails do
  912.      repeat
  913.         MouseStatusWin(L,M,R,X,Y);
  914.         if (X = X1) and (Y = Y2) and L then
  915.            GridMoveIt(Listdetails,7);
  916.         DelayIt(L,InWindow,WaitTime);
  917.      until not L;
  918.   end; { ScrollLeftOne }
  919.  
  920.   procedure ScrollRightOne;
  921.   {}
  922.   begin
  923.      with ListDetails do
  924.      repeat
  925.         MouseStatusWin(L,M,R,X,Y);
  926.         if (X = pred(X2)) and (Y = Y2) and L then
  927.            GridMoveIt(ListDetails,8);
  928.         DelayIt(L,InWindow,WaitTime);
  929.      until not L;
  930.   end; { ScrollRightOne }
  931.  
  932.   procedure ScrollLeftward;
  933.   {}
  934.   begin
  935.      with ListDetails do
  936.      repeat
  937.         MouseStatusWin(L,M,R,X,Y);
  938.         if StartingCol <> RowLock then
  939.         begin
  940.            if (Y = Y2) and (X >= succ(X1)) and (X <= ElevatorX) and L then
  941.               GridMoveIt(ListDetails,7);
  942.            DelayIt(L,InWindow,WaitTime);
  943.         end;
  944.      until not L;
  945.   end; { ScrollLeftward }
  946.  
  947.   procedure ScrollRightward;
  948.   {}
  949.   begin
  950.      with ListDetails do
  951.      repeat
  952.         MouseStatusWin(L,M,R,X,Y);
  953.         if StartingCol <> LastCol then
  954.         begin
  955.            if (Y = Y2) and (X <= X2-2) and (X >= ElevatorX) and L then
  956.               GridMoveIt(ListDetails,8);   {PgDn effect}
  957.            DelayIt(L,InWindow,WaitTime);
  958.         end;
  959.      until not L;
  960.   end; { ScrollRightward }
  961.  
  962.   procedure ScrollDragElevator;
  963.   {}
  964.   var
  965.     OldY:byte;
  966.     NewActive:longint;
  967.   begin
  968.      OldY := Y;
  969.      with ListDetails do
  970.      repeat
  971.         MouseStatusWin(L,M,R,X,Y);
  972.         if (X = X2) and (Y < BotY) and (Y > TopY) and (Y <> OldY) and L then
  973.         begin
  974.            OldY := Y;
  975.            if Y = succ(TopY) then
  976.               NewActive := 1
  977.            else if Y = pred(BotY) then
  978.               NewActive := TotalNodes
  979.            else
  980.               NewActive := TotalNodes * (Y - TopY) div (BotY-TopY);
  981.            if NewActive <> ActiveNode then
  982.            begin
  983.               ActiveNode := NewActive;
  984.               TopNode := NewActive;
  985.               GridRefresh(ListDetails,HiStatus);
  986.            end;
  987.            if WindowHasFocus then
  988.               WinDrawTop;
  989.         end;
  990.      until not L;
  991.   end; { ScrollElevator }
  992.  
  993. begin
  994.    with ListDetails do
  995.    begin
  996.       InWindow := WindowHasFocus;
  997.       WaitTime := KeyVars.InitScrollDelay;
  998.       repeat
  999.          MouseStatusWin(L,M,R,X,Y);
  1000.          if L and (Y = Y2) then
  1001.          begin
  1002.             if X = X1 then
  1003.                ScrollLeftOne
  1004.             else if X = pred(X2) then
  1005.                ScrollRightOne
  1006.             else    {mouse pressed along scroll bar body}
  1007.             begin
  1008.                ElevatorX := GetVScrollBarElevator(X1,pred(X2),StartingCol,LastCol);
  1009.                if ((X = succ(X1)) and (X=ElevatorX) and (StartingCol > RowLock))
  1010.                or (X > X1) and (X < ElevatorX) then
  1011.                   ScrollLeftward
  1012.                else if ((X = X2-2) and (X=ElevatorX)
  1013.                         and
  1014.                         (StartingCol < LastCol)
  1015.                        )
  1016.                        or ((X <= X2-2) and (X > ElevatorX))  then
  1017.                   ScrollRightward
  1018.                else {user is dragging elevator}
  1019.                   ScrollDragElevator;
  1020.              end;
  1021.          end;
  1022.       until not L;
  1023.       MouseRelease;
  1024.    end;
  1025. end; { GridMouseHScroll }
  1026.  
  1027. procedure GridMouseEndHome(var ListDetails: ListCfg);
  1028. {Moves to lower right corner of grid}
  1029. begin
  1030.    with Listdetails Do
  1031.    begin
  1032.       if TabsArrayPtr <> nil then
  1033.       begin
  1034.          StartingCol := TabsArrayPtr^[TabsArrayDim];
  1035.          TabsArrayPos := TabsArrayDim;
  1036.       end
  1037.       else
  1038.          StartingCol := LastCol;
  1039.       ActiveNode := TotalNodes;
  1040.       TopNode := ActiveNode;
  1041.       GridRefresh(ListDetails,HiStatus);
  1042.       MouseRelease;
  1043.    end;
  1044. end; { GridMouseEndHome }
  1045.  
  1046. function GridTargetPick(var ListDetails: ListCfg;X,Y:byte): longint;
  1047. {return the pick number of the pick pointed to by
  1048.  the coordinates X,Y. If no pick is at those coordinates, a
  1049.  0 is returned}
  1050. begin
  1051.    with ListDetails do
  1052.    begin
  1053.       if  (X >= X1)
  1054.       and (X < X2)   {last column is for scroll bar}
  1055.       and (Y >= Y1 + RowLock)
  1056.       and (Y <= Y2 - ord(LastCol > X2-X1))
  1057.       then
  1058.       begin
  1059.          X := succ(X - X1);
  1060.          Y := succ(Y - Y1 - RowLock);
  1061.          if pred(TopNode) + Y <= TotalNodes then
  1062.          begin
  1063.          (*
  1064.             KeyVars.LastX := pred(TopNode) + Y;
  1065.             GridTargetPick := KeyVars.LastX;
  1066.          *)
  1067.             GridTargetPick := pred(TopNode) + Y;
  1068.             exit;
  1069.          end;
  1070.       end;
  1071.       GridTargetPick := 0;
  1072.       KeyVars.LastX := 0;
  1073.    end;
  1074. end; {GridTargetPick}
  1075.  
  1076. procedure GridMouseSelect(var ListDetails: ListCfg);
  1077. {Called when mouse pressed on field and held down}
  1078. var
  1079.   L,M,R: boolean;
  1080.   X,Y:byte;
  1081.   OldAct,
  1082.   NewAct: longint;
  1083.  
  1084.    function OnActiveNode: boolean;
  1085.    {}
  1086.    begin
  1087.       MouseStatusWin(L,M,R,X,Y);
  1088.       with ListDetails do
  1089.          OnActiveNode := (ActiveNode = GridTargetPick(Listdetails,X,Y));
  1090.    end; { OnActiveNode }
  1091.  
  1092.    function CheckforTagChange:boolean;
  1093.    {}
  1094.    begin
  1095.       CheckForTagChange := false;
  1096.       with Listdetails do
  1097.       if AllowTagging then
  1098.       begin
  1099.          if OnActiveNode and L then
  1100.          begin
  1101.             ToggleTagState(Listdetails);
  1102.             if WindowHasFocus then
  1103.                WinDrawTop;
  1104.             MouseRelease;
  1105.             if OnActiveNode then   {see if still on item if not re-toggle the mouse}
  1106.                CheckForTagChange := true
  1107.             else
  1108.                ToggleTagState(Listdetails);
  1109.          end;
  1110.       end;
  1111.    end; { CheckforTagChange }
  1112.  
  1113. begin
  1114.    if not CheckForTagChange then
  1115.    with ListDetails do
  1116.    repeat
  1117.       MouseStatusWin(L,M,R,X,Y);
  1118.       if L then
  1119.       begin
  1120.          OldAct := ActiveNode;
  1121.          NewAct := GridTargetPick(Listdetails,X,Y);
  1122.          if (NewAct <> 0) and (NewAct <> OldAct) then
  1123.          begin
  1124.             ActiveNode := NewAct;
  1125.             GridWriteItem(ListDetails,OldAct,HiStatus);
  1126.             GridWriteItem(ListDetails,ActiveNode,HiStatus);
  1127.             if WindowHasFocus then
  1128.                WinDrawTop;
  1129.          end;
  1130.       end;
  1131.    until not L;
  1132.    MouseRelease;
  1133. end; {GridMouseSelect}
  1134.  
  1135. procedure GridProcessKey(var ListDetails: ListCfg;var K:word;X,Y:byte;MakeLocal:boolean);
  1136. {}
  1137. var
  1138.    Ch: char;
  1139.    OldAct: longint;
  1140. begin
  1141.    with ListDetails do
  1142.    begin
  1143.       CharHook(K,X,Y); {call user hook}
  1144.       if MakeLocal then
  1145.          if IsWinKey(K,X,Y) then
  1146.             WinProcessKey(K,X,Y);
  1147.       K := CapitalWord(K);
  1148.       if (K = 500) or (K = 540) then
  1149.       begin
  1150.          if MakeLocal then {convert to local coords}
  1151.          begin
  1152.             X := WinLocalX(0,X);
  1153.             Y := WinLocalY(0,Y);
  1154.          end;
  1155.          if K = 500 then
  1156.          begin
  1157.             if ((LastCol > X2-X1) and (TotalNodes > succ(Y2-Y1)))
  1158.                      and (X=X2)
  1159.                      and (Y=Y2) then
  1160.                GridMouseEndHome(Listdetails)
  1161.             else if (X = X2) and (TotalNodes > succ(Y2-Y1)) then
  1162.                GridMouseVScroll(Listdetails)
  1163.             else if (LastCol > X2-X1) and (Y = Y2) then
  1164.                GridMouseHScroll(Listdetails)
  1165.             else
  1166.                GridMouseSelect(Listdetails);
  1167.          end
  1168.          else if GridTargetPick(Listdetails,X,Y) = ActiveNode then
  1169.             K := 540  {double click}
  1170.          else
  1171.             K := 0;
  1172.       end
  1173.       else if K = ListVars.ToggleKey then
  1174.            ToggleTagState(Listdetails)
  1175.       else if K = ListVars.TagKey then
  1176.            SetTag(Listdetails,true)
  1177.       else if K = ListVars.UnTagKey then
  1178.            SetTag(Listdetails,false)
  1179.       else if K = ListVars.TagAllKey then
  1180.            SetTagAll(Listdetails,true)
  1181.       else if K = ListVars.UnTagAllKey then
  1182.            SetTagAll(Listdetails,false)
  1183.       else
  1184.       case K of
  1185.          328: GridMoveIt(ListDetails,1);
  1186.          336: GridMoveIt(ListDetails,2);
  1187.          329: GridMoveIt(ListDetails,3);
  1188.          337: GridMoveIt(ListDetails,4);
  1189.          327: GridMoveIt(ListDetails,5);
  1190.          335: GridMoveIt(ListDetails,6);
  1191.          331: GridMoveIt(ListDetails,7);
  1192.          333: GridMoveIt(ListDetails,8);
  1193.          602: if WindowHasFocus then
  1194.                  GridWindowStretch(Listdetails);
  1195.          else if (K >= 55) and (K <= 255) then
  1196.          begin
  1197.             Ch := chr(CapitalWord(K));
  1198.             OldAct := ActiveNode;
  1199.             if GridScrollChar(Listdetails,Ch) then
  1200.                GridRefresh(ListDetails,HiStatus)
  1201.             else if OldAct <> ActiveNode then
  1202.             begin
  1203.                GridWriteItem(ListDetails,OldAct,HiStatus);
  1204.                GridWriteItem(ListDetails,ActiveNode,HiStatus);
  1205.             end;
  1206.          end;
  1207.       end; {case}
  1208.       WriteHeadingsHook(@Listdetails);
  1209.       HindHook(@ListDetails);
  1210.    end;
  1211. end; { GridProcessKey }
  1212.  
  1213. function DisplayGridEngine(var ListDetails: ListCfg;Tit:StrScreen): byte;
  1214. {INTERNAL}
  1215. var
  1216.   Handle: integer;
  1217.  
  1218.    procedure SetWindow;
  1219.    {}
  1220.    begin
  1221.       with ListVars do
  1222.       with ListDetails do
  1223.       begin
  1224.          Handle := WinCreate(WX1,WY1,WX2,WY2,WStyle);
  1225.          WinSetType(Handle,WrapWinType);
  1226.          WinSetTitle(Handle,Tit);
  1227.          WinSetShowNum(Handle,false);
  1228.          WinSetColor(Handle,WinBorder,Col[ListBorder1]);
  1229.          WinSetColor(Handle,WinBorder3DOut,Col[ListBorder1]);
  1230.          WinSetColor(Handle,WinBorder3dIn,Col[ListBorder2]);
  1231.          WinSetColor(Handle,WinBorderOff,Col[ListBorderOff]);
  1232.          WinSetColor(Handle,WinIcons,Col[ListIcons]);
  1233.          WinSetColor(Handle,WinBody,Col[ListNorm1]);
  1234.          WinSetColor(Handle,WinTitle,Col[ListTitle]);
  1235.          if ListDetails.ColWidth <> 0 then
  1236.             WinSetMinSize(Handle,ListDetails.ColWidth+2+2*ord(WinStyle in [7,8]),WinVars.MinDepth);
  1237.          WinPaint(Handle);
  1238.       end;
  1239.    end; {SetWindow}
  1240.  
  1241. begin
  1242.    with ListDetails do
  1243.    begin
  1244.       if WX1 = 0 then  {user hasn't set the window}
  1245.       begin
  1246.          WX1 := ListVars.WX1;
  1247.          WY1 := ListVars.WY1;
  1248.          WX2 := ListVars.WX2;
  1249.          WY2 := ListVars.WY2;
  1250.       end;
  1251.       if AllowTagging then {Jubelt}
  1252.          inc(WX2);
  1253.       SetInnerDimensions(Listdetails);
  1254.       InWindow := true;
  1255.       SetWindow;
  1256.       WinDisplay(Handle);
  1257.       if (TabsArrayPtr = nil) and (ColumnLock > 0) then
  1258.          StartingCol := succ(ColumnLock);
  1259.    end;
  1260.    GridRefresh(ListDetails,HiStatus);
  1261.    ListDetails.HindHook(@ListDetails); {call it once after window is created}
  1262.    DisplayGridEngine := Handle;
  1263. end; { DisplayGridEngine }
  1264.  
  1265. procedure ProcessGridInput(var ListDetails: ListCfg; OnDeskTop:boolean);
  1266. {}
  1267. begin
  1268.    with Listdetails do
  1269.    with KeyVars do
  1270.    begin
  1271.       GridProcessKey(ListDetails,LastKey,LastX,LastY,true);
  1272.       if not OnDeskTop
  1273.       and (
  1274.               (LastKey = 600)
  1275.            or (LastKey = 27)
  1276.            or ((LastKey = 540) and (LastX <> 0))
  1277.            or (LastKey = 13)
  1278.           ) then
  1279.       begin
  1280.           LastAction := SelectHook(@ListDetails);
  1281.           if LastAction = Refresh then
  1282.           begin
  1283.              case DataType of
  1284.                 SourceStrLL: TotalNodes := StringLL(dataSource^).TotalNodes;
  1285.                 SourceSLL: TotalNodes := LinkVars.ActiveSLL^.TotalNodes;
  1286.                 SourceDLL: TotalNodes := LinkVars.ActiveDLL^.TotalNodes;
  1287.              end;
  1288.              if (ActiveNode > TotalNodes) or (TopNode > TotalNodes) then
  1289.              begin
  1290.                 ActiveNode := 1;
  1291.                 TopNode := 1;
  1292.              end;
  1293.              GridRefresh(ListDetails,HiStatus)
  1294.           end;
  1295.       end
  1296.       else
  1297.       begin
  1298.          if LastKey = 600 then
  1299.             LastAction := Escaped
  1300.          else
  1301.             LastAction := none;
  1302.       end;
  1303.    end;
  1304. end; { ProcessGridInput }
  1305.  
  1306. procedure RunGrid(var ListDetails: ListCfg;Tit:StrScreen);
  1307. {}
  1308. var Handle:integer;
  1309. begin
  1310.    Handle := DisplayGridEngine(Listdetails,Tit);
  1311.    WinDrawAll;
  1312.    with Listdetails do
  1313.    with KeyVars do
  1314.    repeat
  1315.       GetInput;
  1316.       ProcessGridInput(Listdetails,false);
  1317.       WinDrawAll;
  1318.    until LastAction in [Stop1..Escaped];
  1319.    ListVars.LastActiveItem := ListDetails.ActiveNode;
  1320.    WinDispose(Handle);
  1321.    MouseRelease;
  1322. end; {RunGrid}
  1323.  
  1324.  
  1325. {$IFOPT F-}
  1326.    {$DEFINE FOFF}
  1327.    {$F+}
  1328. {$ENDIF}
  1329. procedure GridProcessKeyOnDesktop;
  1330. {}
  1331. var
  1332.    Handle: integer;
  1333.    WinP: WStructurePtr;
  1334.    LDP : ^ListCfg;
  1335.    K: word;
  1336.    X,Y: byte;
  1337. begin
  1338.    Handle := WinWithFocus;
  1339.    WinP := WinPtr(Handle);
  1340.    LDP := WinP^.UserData;
  1341.    ProcessGridInput(LDP^,true);
  1342.    if LDP^.LastAction in [Stop1..Escaped] then
  1343.       if ListCloseHandler(Handle) then
  1344.          {close aborted};
  1345. end; { GridProcessKeyOnDesktop }
  1346.  
  1347. {$IFDEF FOFF}
  1348.    {$F-}
  1349.    {$UNDEF FOFF}
  1350. {$ENDIF}
  1351.  
  1352. function LaunchGrid(var ListDetails: ListCfg;Tit:StrScreen; CloseProc:ListCloseProc): byte;
  1353. {}
  1354. var
  1355.    WinP: WStructurePtr;
  1356.    Handle: byte;
  1357. begin
  1358.    WinFadeTopWin;
  1359.    Listdetails.DeskListCloseCallBack := CloseProc;
  1360.    if WinVars.DesktopFocusStyle <> 0 then
  1361.       Listdetails.WStyle := WinVars.DesktopFocusStyle;
  1362.    Handle := DisplayGridEngine(Listdetails,Tit);
  1363.    if Handle <> 0 then
  1364.    begin
  1365.       WinP := WinPtr(Handle);
  1366.       if WinP <> nil then
  1367.       begin
  1368.          WinP^.ProcessKeyProc := GridProcessKeyOnDeskTop;
  1369.          WinP^.CloseWinProc := ListCloseHandler;
  1370.          WinP^.ChangeFocusProc := ListFocusHandler;
  1371.          WinP^.UserData := @ListDetails;
  1372.       end;
  1373.       WinDrawTop;
  1374.    end;
  1375.    LaunchGrid := Handle;
  1376. end; {LaunchGrid}
  1377.  
  1378. {|||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1379. {                                                     }
  1380. {       U N I T     I N I T I A L I Z A T I O N       }
  1381. {                                                     }
  1382. {|||||||||||||||||||||||||||||||||||||||||||||||||||||}
  1383. procedure GridDefaultSettings;
  1384. {}
  1385. begin
  1386.    GridVars.GridCorner := '≥';
  1387. end; { GridDefaultSettings }
  1388.  
  1389. procedure GoldGridInit;
  1390. {}
  1391. begin
  1392.    with GridVars do
  1393.    begin
  1394.       LastECode := 0;
  1395.       EMsgFunc := GridEMsg;
  1396.    end;
  1397.    GridDefaultSettings;
  1398. end; {GoldGridInit}
  1399.  
  1400. begin
  1401.    GoldGridInit;
  1402. end.
  1403.